package org.jivesoftware.smack;

import com.easemob.util.EMLog;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.sasl.SASLAnonymous;
import org.jivesoftware.smack.sasl.SASLCramMD5Mechanism;
import org.jivesoftware.smack.sasl.SASLDigestMD5Mechanism;
import org.jivesoftware.smack.sasl.SASLExternalMechanism;
import org.jivesoftware.smack.sasl.SASLGSSAPIMechanism;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.sasl.SASLPlainMechanism;

public class SASLAuthentication
  implements UserAuthentication
{
  private static final long PACKET_TIMER_OUT_TIME = 20000L;
  private static Map<String, Class<? extends SASLMechanism>> implementedMechanisms = new HashMap();
  private static List<String> mechanismsPreferences = new ArrayList();
  private Connection connection;
  private Collection<String> serverMechanisms = new ArrayList();
  private SASLMechanism currentMechanism = null;
  private boolean saslNegotiated;
  private boolean saslFailed;
  private boolean resourceBinded;
  private boolean sessionSupported;
  private String errorCondition;

  static
  {
    registerSASLMechanism("EXTERNAL", SASLExternalMechanism.class);
    registerSASLMechanism("GSSAPI", SASLGSSAPIMechanism.class);
    registerSASLMechanism("DIGEST-MD5", SASLDigestMD5Mechanism.class);
    registerSASLMechanism("CRAM-MD5", SASLCramMD5Mechanism.class);
    registerSASLMechanism("PLAIN", SASLPlainMechanism.class);
    registerSASLMechanism("ANONYMOUS", SASLAnonymous.class);
    supportSASLMechanism("DIGEST-MD5", 0);
    supportSASLMechanism("PLAIN", 1);
    supportSASLMechanism("ANONYMOUS", 2);
  }

  public static void registerSASLMechanism(String paramString, Class<? extends SASLMechanism> paramClass)
  {
    implementedMechanisms.put(paramString, paramClass);
  }

  public static void unregisterSASLMechanism(String paramString)
  {
    implementedMechanisms.remove(paramString);
    mechanismsPreferences.remove(paramString);
  }

  public static void supportSASLMechanism(String paramString)
  {
    mechanismsPreferences.add(0, paramString);
  }

  public static void supportSASLMechanism(String paramString, int paramInt)
  {
    mechanismsPreferences.add(paramInt, paramString);
  }

  public static void unsupportSASLMechanism(String paramString)
  {
    mechanismsPreferences.remove(paramString);
  }

  public static List<Class<? extends SASLMechanism>> getRegisterSASLMechanisms()
  {
    ArrayList localArrayList = new ArrayList();
    Iterator localIterator = mechanismsPreferences.iterator();
    while (localIterator.hasNext())
    {
      String str = (String)localIterator.next();
      localArrayList.add((Class)implementedMechanisms.get(str));
    }
    return localArrayList;
  }

  SASLAuthentication(Connection paramConnection)
  {
    this.connection = paramConnection;
    init();
  }

  public boolean hasAnonymousAuthentication()
  {
    return this.serverMechanisms.contains("ANONYMOUS");
  }

  public boolean hasNonAnonymousAuthentication()
  {
    return (!this.serverMechanisms.isEmpty()) && ((this.serverMechanisms.size() != 1) || (!hasAnonymousAuthentication()));
  }

  public String authenticate(String paramString1, String paramString2, CallbackHandler paramCallbackHandler)
    throws XMPPException
  {
    Object localObject1 = null;
    Object localObject3 = mechanismsPreferences.iterator();
    Object localObject2;
    while (((Iterator)localObject3).hasNext())
    {
      localObject2 = (String)((Iterator)localObject3).next();
      if ((implementedMechanisms.containsKey(localObject2)) && (this.serverMechanisms.contains(localObject2)))
      {
        localObject1 = localObject2;
        break;
      }
    }
    if (localObject1 != null)
      try
      {
        localObject2 = (Class)implementedMechanisms.get(localObject1);
        localObject3 = ((Class)localObject2).getConstructor(new Class[] { SASLAuthentication.class });
        this.currentMechanism = ((SASLMechanism)((Constructor)localObject3).newInstance(new Object[] { this }));
        this.currentMechanism.authenticate(paramString1, this.connection.getHost(), paramCallbackHandler);
        synchronized (this)
        {
          if ((!this.saslNegotiated) && (!this.saslFailed))
            try
            {
              EMLog.d("SASLAuthentication", "waiting for authentiation response!");
              wait(50000L);
            }
            catch (InterruptedException localInterruptedException)
            {
            }
        }
        throwExceptionIfConnectionDisconnected();
        if (this.saslFailed)
        {
          if (this.errorCondition != null)
            throw new XMPPException("SASL authentication " + localObject1 + " failed: " + this.errorCondition);
          throw new XMPPException("SASL authentication failed using mechanism " + localObject1);
        }
        if (!this.saslNegotiated)
          break label310;
        return bindResourceAndEstablishSession(paramString2);
      }
      catch (XMPPException localXMPPException)
      {
        throw localXMPPException;
      }
      catch (Exception localException)
      {
        localException.printStackTrace();
      }
    else
      throw new XMPPException("SASL Authentication failed. No known authentication mechanisims.");
    label310: throw new XMPPException("SASL authentication failed");
  }

  private void throwExceptionIfConnectionDisconnected()
    throws XMPPException
  {
    if ((this.connection != null) && (!this.connection.isConnected()))
      throw new XMPPException("Connection already disconnected!.");
  }

  public String authenticate(String paramString1, String paramString2, String paramString3)
    throws XMPPException
  {
    Object localObject1 = null;
    Object localObject3 = mechanismsPreferences.iterator();
    Object localObject2;
    while (((Iterator)localObject3).hasNext())
    {
      localObject2 = (String)((Iterator)localObject3).next();
      if ((implementedMechanisms.containsKey(localObject2)) && (this.serverMechanisms.contains(localObject2)))
      {
        localObject1 = localObject2;
        break;
      }
    }
    if (localObject1 != null)
      try
      {
        localObject2 = (Class)implementedMechanisms.get(localObject1);
        localObject3 = ((Class)localObject2).getConstructor(new Class[] { SASLAuthentication.class });
        this.currentMechanism = ((SASLMechanism)((Constructor)localObject3).newInstance(new Object[] { this }));
        this.currentMechanism.authenticate(paramString1, this.connection.getServiceName(), paramString2);
        synchronized (this)
        {
          if ((!this.saslNegotiated) && (!this.saslFailed))
            try
            {
              EMLog.d("SASLAuthentication", "waiting for authentiation response!");
              wait(50000L);
            }
            catch (InterruptedException localInterruptedException)
            {
            }
        }
        throwExceptionIfConnectionDisconnected();
        if (this.saslFailed)
        {
          if (this.errorCondition != null)
            throw new XMPPException("SASL authentication " + localObject1 + " failed: " + this.errorCondition);
          throw new XMPPException("SASL authentication failed using mechanism " + localObject1);
        }
        if (this.saslNegotiated)
          return bindResourceAndEstablishSession(paramString3);
        return new NonSASLAuthentication(this.connection).authenticate(paramString1, paramString2, paramString3);
      }
      catch (XMPPException localXMPPException)
      {
        throw localXMPPException;
      }
      catch (Exception localException)
      {
        localException.printStackTrace();
        return new NonSASLAuthentication(this.connection).authenticate(paramString1, paramString2, paramString3);
      }
    return new NonSASLAuthentication(this.connection).authenticate(paramString1, paramString2, paramString3);
  }

  public String authenticateAnonymously()
    throws XMPPException
  {
    try
    {
      this.currentMechanism = new SASLAnonymous(this);
      this.currentMechanism.authenticate(null, null, "");
      synchronized (this)
      {
        if ((!this.saslNegotiated) && (!this.saslFailed))
          try
          {
            EMLog.d("SASLAuthentication", "waiting for authentiation response!");
            wait(5000L);
          }
          catch (InterruptedException localInterruptedException)
          {
          }
      }
      throwExceptionIfConnectionDisconnected();
      if (this.saslFailed)
      {
        if (this.errorCondition != null)
          throw new XMPPException("SASL authentication failed: " + this.errorCondition);
        throw new XMPPException("SASL authentication failed");
      }
      if (this.saslNegotiated)
        return bindResourceAndEstablishSession(null);
      return new NonSASLAuthentication(this.connection).authenticateAnonymously();
    }
    catch (IOException localIOException)
    {
    }
    return new NonSASLAuthentication(this.connection).authenticateAnonymously();
  }

  private String bindResourceAndEstablishSession(String paramString)
    throws XMPPException
  {
    synchronized (this)
    {
      if (!this.resourceBinded)
        try
        {
          wait(50000L);
        }
        catch (InterruptedException localInterruptedException)
        {
        }
    }
    throwExceptionIfConnectionDisconnected();
    if (!this.resourceBinded)
      throw new XMPPException("Resource binding not offered by server");
    ??? = new Bind();
    ((Bind)???).setResource(paramString);
    PacketCollector localPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(((Bind)???).getPacketID()));
    this.connection.sendPacket((Packet)???);
    Bind localBind = (Bind)localPacketCollector.nextResult(20000L);
    localPacketCollector.cancel();
    if (localBind == null)
      throw new XMPPException("No response from the server.");
    if (localBind.getType() == IQ.Type.ERROR)
      throw new XMPPException(localBind.getError());
    String str = localBind.getJid();
    if (this.sessionSupported)
    {
      Session localSession = new Session();
      localPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(localSession.getPacketID()));
      this.connection.sendPacket(localSession);
      IQ localIQ = (IQ)localPacketCollector.nextResult(20000L);
      localPacketCollector.cancel();
      if (localIQ == null)
        throw new XMPPException("No response from the server.");
      if (localIQ.getType() == IQ.Type.ERROR)
        throw new XMPPException(localIQ.getError());
    }
    return str;
  }

  void setAvailableSASLMethods(Collection<String> paramCollection)
  {
    this.serverMechanisms = paramCollection;
  }

  public boolean isAuthenticated()
  {
    return this.saslNegotiated;
  }

  void challengeReceived(String paramString)
    throws IOException
  {
    this.currentMechanism.challengeReceived(paramString);
  }

  void authenticated()
  {
    synchronized (this)
    {
      this.saslNegotiated = true;
      notify();
    }
  }

  void authenticationFailed()
  {
    authenticationFailed(null);
  }

  void authenticationFailed(String paramString)
  {
    synchronized (this)
    {
      this.saslFailed = true;
      this.errorCondition = paramString;
      notify();
    }
  }

  void bindingRequired()
  {
    synchronized (this)
    {
      this.resourceBinded = true;
      notify();
    }
  }

  public void send(Packet paramPacket)
  {
    this.connection.sendPacket(paramPacket);
  }

  void sessionsSupported()
  {
    this.sessionSupported = true;
  }

  protected void init()
  {
    this.saslNegotiated = false;
    this.saslFailed = false;
    this.resourceBinded = false;
    this.sessionSupported = false;
  }
}

/* Location:           D:\hygieia\userclient\common\libs\easemobchat_2.1.8.jar
 * Qualified Name:     org.jivesoftware.smack.SASLAuthentication
 * JD-Core Version:    0.6.1
 */